package org.batatasframework.support.database.values;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.batatasframework.support.database.spi.ResultWritable;
import org.batatasframework.support.database.sql.field.SelectFragment;
import org.batatasframework.support.format.StringLimitsFormat;
import cn.bonoon.kernel.util.StringHelper;

public class StringValueHolder extends AbstractSingleValueHolder{
	
	private final Object format;
	
	public StringValueHolder(SelectFragment field, String alias, Object format) {
		super(field, alias);
		this.format = format;
	}
	
	@Override
	public FieldValue read(ResultSet rs) throws Exception {
		return new StringValue(rs.getString(alias));
	}

	@Override
	public StatisticsTotal createStatistics() {
		return new StringStatistics();
	}
	
	public class StringValue extends AbstractValue<String>{
		public StringValue(String value){
			super(value);
		}

		@Override
		public Object targetValue() {
			/*
			 * 1. 是否定义了值限制在指定的字符串集里
			 * 2. 非null值直接返回
			 * 3. 如果format为String类型，则value=null时替换返回值
			 * 4. 返回空""字符串
			 */
			if(format instanceof StringLimitsFormat){
				return ((StringLimitsFormat)format).format(value);
			}
			
			if(null != value){
				return value;
			}
			
			if(format instanceof String){
				return format.toString();
			}
			
			return "";
		}
	}
	
	class StringStatistics implements StatisticsTotal{
		
		/*
		 * 是否允许动态增长
		 */
		private final boolean dynamic;

		private List<StringStatisticsHead> statisticsHeads = new ArrayList<>();
		private StringStatisticsHead nullHead;
		
		public StringStatistics() {
			if(format instanceof StringLimitsFormat){
				StringLimitsFormat slFormat = (StringLimitsFormat)format;
				dynamic = false;
				String nullValue = slFormat.getNullName();
				if(slFormat.isNullable() && !nullValue.isEmpty()){
					nullHead = new StringStatisticsHead(nullValue);
				}
				for(String li : slFormat.getLimits()){
					statisticsHeads.add(new StringStatisticsHead(li));
				}
			}else{
				dynamic = true;
			}
		}
		
		private class StringStatisticsValue implements StatisticsValue{
			
			private Map<String, StringAutoIncrease> values = new HashMap<>();
			private StringAutoIncrease nullCell;
			public StringStatisticsValue(){
				if(null != nullHead){
					nullCell = nullHead.newCell();
				}
				
				for(StringStatisticsHead item : statisticsHeads){
					values.put(item.name, item.newCell());
				}
			}
			
			@Override
			public void read(ResultSet rs) throws Exception {
				String val = rs.getString(alias);
				StringAutoIncrease valItem = null;
				if(StringHelper.isNotEmpty(val)){
					valItem = values.get(val);
					if(null == valItem && dynamic){
						//可以动态增加项的
						StringStatisticsHead dynHead = new StringStatisticsHead(val);
						statisticsHeads.add(dynHead);
						valItem = dynHead.newCell();
						values.put(val, valItem);
					}
				}
				if(null == valItem) valItem = nullCell;
				if(null != valItem) valItem.increase();
			}

			@Override
			public void writeTo(ResultWritable resultWriter) throws Exception {
				if(null != nullHead && nullHead.sumValue > 0){
					resultWriter.append(nullCell.getValue());
				}
				
				for(StringStatisticsHead item : statisticsHeads){
					StringAutoIncrease cellValue = values.get(item.name);
					
					if(null != cellValue){
						resultWriter.append(cellValue.getValue());
					}else{
						resultWriter.append("");
					}
				}
			}
			
		}

		@Override
		public StatisticsValue newValue() {
			return new StringStatisticsValue();
		}

		@Override
		public void writeTo(ResultWritable resultWriter) throws Exception {
			if(null != nullHead && nullHead.sumValue > 0) resultWriter.append(nullHead.sumValue);
			
			for(StringStatisticsHead item : statisticsHeads){
				resultWriter.append(item.sumValue);
			}
		}

		@Override
		public String[] getItemNames() {
			String[] names;
			int i = 0;
			if(null != nullHead && nullHead.sumValue > 0){
				names = new String[statisticsHeads.size() + 1];
				names[i++] = nullHead.name;
			}else{
				names = new String[statisticsHeads.size()];
			}
			
			for(StringStatisticsHead item : statisticsHeads){
				names[i++] = item.name;
			}
			
			return names;
		}
	}
}

interface StringAutoIncrease{
	int getValue();
	void increase();
}

class StringStatisticsHead{
	final String name;
	int sumValue;
	
	public StringStatisticsHead(String name){
		this.name = name;
	}
	
	public StringAutoIncrease newCell(){
		return new StringStatisticsItemImpl();
	}
	
	public class StringStatisticsItemImpl implements StringAutoIncrease{
		private int value;

		@Override
		public int getValue() {
			return value;
		}

		@Override
		public void increase() {
			value++;
			sumValue++;
		}
	}
}
